using System.Reflection;
using Microsoft.EntityFrameworkCore;
using ProduceBasicData.Api.DTO;
using ProduceBasicData.Infrastructure;
using ProduceBasicData.Domain.Entities;

namespace ProduceBasicData.Api.Services
{
    /// <summary>
    /// 编码规则元数据服务实现
    /// </summary>
    public class CodeRuleMetadataService : ICodeRuleMetadataService
    {
        private readonly MyDBContext _dbContext;
        private readonly Assembly _domain;

        public CodeRuleMetadataService(MyDBContext dbContext)
        {
            _dbContext = dbContext;
            _domain = typeof(BaseEntity).Assembly;
        }

        /// <summary>
        /// 获取业务名称列表
        /// </summary>
        public async Task<List<BusinessDto>> GetBusinessesAsync()
        {
            var businesses = new List<BusinessDto>();

            // 获取所有继承自BaseEntity的类型
            var entityTypes = _domain.GetTypes()
                .Where(t => typeof(BaseEntity).IsAssignableFrom(t) && !t.IsAbstract)
                .ToList();

            foreach (var entityType in entityTypes)
            {
                // 检查是否有系统编码字段
                var hasSystemCodeField = entityType.GetProperties()
                    .Any(p => IsSystemCodeField(p));

                if (hasSystemCodeField)
                {
                    businesses.Add(new BusinessDto
                    {
                        Name = GetDisplayName(entityType),
                        ClassFullName = entityType.FullName ?? entityType.Name,
                        Description = GetEntityDescription(entityType)
                    });
                }
            }

            return businesses.OrderBy(b => b.Name).ToList();
        }

        /// <summary>
        /// 获取指定实体的字段列表
        /// </summary>
        public async Task<List<FieldDto>> GetFieldsAsync(string classFullName)
        {
            var entityType = _domain.GetType(classFullName);
            if (entityType == null)
            {
                return new List<FieldDto>();
            }

            var fields = new List<FieldDto>();

            var properties = entityType.GetProperties()
                .Where(p => p.CanWrite && p.PropertyType == typeof(string))
                .ToList();

            foreach (var property in properties)
            {
                fields.Add(new FieldDto
                {
                    Name = property.Name,
                    DisplayName = GetPropertyDisplayName(property),
                    Type = property.PropertyType.Name,
                    IsDate = false,
                    IsSystemCode = IsSystemCodeField(property),
                    Description = GetPropertyDescription(property)
                });
            }

            return fields.OrderBy(f => f.Name).ToList();
        }

        /// <summary>
        /// 获取日期字段列表
        /// </summary>
        public async Task<List<FieldDto>> GetDateFieldsAsync(string classFullName)
        {
            var entityType = _domain.GetType(classFullName);
            if (entityType == null)
            {
                return new List<FieldDto>();
            }

            var dateFields = new List<FieldDto>();

            var properties = entityType.GetProperties()
                .Where(p => p.CanWrite && (p.PropertyType == typeof(DateTime) || p.PropertyType == typeof(DateTime?)))
                .ToList();

            foreach (var property in properties)
            {
                dateFields.Add(new FieldDto
                {
                    Name = property.Name,
                    DisplayName = GetPropertyDisplayName(property),
                    Type = property.PropertyType.Name,
                    IsDate = true,
                    IsSystemCode = false,
                    Description = GetPropertyDescription(property)
                });
            }

            return dateFields.OrderBy(f => f.Name).ToList();
        }

        /// <summary>
        /// 判断是否为系统编码字段
        /// </summary>
        private bool IsSystemCodeField(PropertyInfo property)
        {
            var systemCodeFieldNames = new[]
            {
                // 基础编码字段
                "Code", "SystemCode", "SytemNo",
                
                // 订单相关
                "OrderNumber", "Order_no", "RelatedOrderNumber",
                
                // 报告相关
                "Report_no", "ReportNo",
                
                // 产品相关
                "BOMCode", "Product_no", "ProductNo", "MaterialNo",
                
                // 设备相关
                "DeviceTypeCode", "FormCode", "ProjectCode",
                
                // 车间相关
                "Workshopcode", "Workstationcode", "Productioncode", "Processcode",
                
                // 仓库相关
                "LocationCode", "ZoneCode", "MaterialCode", "SourceLocationCode", "TargetLocationCode",
                
                // 用户权限相关
                "UserCode", "RoleCode", "PermissionCode",
                
                // 字典相关
                "GroupTypeCode", "TypeCode", "DictTypeCode",
                
                // 检验相关
                "InspectionSchemeCode", "InspectionNo", "IncomingCode",
                
                // 工艺相关
                "CraftNo",
                
                // 发票相关
                "Kpch", "PurchaseCode",
                
                // 供应商相关
                "SocialCreditCode"
            };

            return systemCodeFieldNames.Contains(property.Name);
        }

        /// <summary>
        /// 获取实体显示名称
        /// </summary>
        private string GetDisplayName(Type entityType)
        {
            // 从类名中提取显示名称
            var className = entityType.Name;
            
            // 移除常见的后缀
            var suffixes = new[] { "Model", "Entity", "Info" };
            foreach (var suffix in suffixes)
            {
                if (className.EndsWith(suffix))
                {
                    className = className.Substring(0, className.Length - suffix.Length);
                    break;
                }
            }

            return className;
        }

        /// <summary>
        /// 获取实体描述
        /// </summary>
        private string? GetEntityDescription(Type entityType)
        {
            // 可以扩展为从XML文档注释中获取描述
            return null;
        }

        /// <summary>
        /// 获取属性显示名称
        /// </summary>
        private string GetPropertyDisplayName(PropertyInfo property)
        {
            // 可以扩展为从DisplayAttribute中获取显示名称
            return property.Name;
        }

        /// <summary>
        /// 获取属性描述
        /// </summary>
        private string? GetPropertyDescription(PropertyInfo property)
        {
            // 可以扩展为从XML文档注释中获取描述
            return null;
        }
    }
}